﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ChartEdit
{
    public class SyncTrackSection : List<SyncTrackEntry>
    {
        public const string SectionName = "SyncTrack";


        public bool ContainsOffset( int offset )
        {
            foreach ( SyncTrackEntry entry in this )
            {
                if ( entry.Offset == offset )
                    return true;
            }
            return false;
        }

        public SyncTrackEntry GetByOffset( int offset )
        {
            foreach ( SyncTrackEntry entry in this )
            {
                if ( entry.Offset == offset )
                    return entry;
            }
            return null;
        }
        public SyncTrackEntry GetByIndex( int index )
        {
            return this[ index ];
        }
    }

    public enum SyncType
    {
        BPM,
        TimeSignature,
        Anchor,
    }
    public class SyncTrackEntry
    {
        static readonly Regex SyncTrackRegex = new Regex( "(?<offset>\\d+)\\s*\\=\\s*(?<type>.*?)\\s*(?<value>\\d+)", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline );

        public int Offset { get; set; }

        public SyncType Type { get; set; }

        public int BPM { get; set; }
        public float FloatBPM { get; set; }
        public int TimeSignature { get; set; }
        public int Anchor { get; set; }


        public static SyncTrackEntry Parse( string entryStr )
        {
            Match match = SyncTrackRegex.Match( entryStr );

            if ( !match.Success )
                return null;

            SyncTrackEntry entry = new SyncTrackEntry();

            int offset = int.Parse( match.Groups[ "offset" ].Value.Trim() );
            string type = match.Groups[ "type" ].Value.Trim();
            int value;
            try
            {
                value = int.Parse(match.Groups["value"].Value.Trim());
            }
            catch(System.OverflowException)
            {
                value = Int32.MaxValue;
            }

            entry.Offset = offset;

            switch ( type )
            {

                case "A":
                    entry.Anchor = value;
                    entry.Type = SyncType.Anchor;
                    break;

                case "TS":
                    entry.TimeSignature = value;
                    entry.Type = SyncType.TimeSignature;
                    break;

                case "B":
                    entry.BPM = value;
                    entry.FloatBPM = ( float )value / 1000f;
                    entry.Type = SyncType.BPM;
                    break;

            }

            return entry;
        }
    }
}
